const { getData } = require('./storage')
const { ipcMain, dialog } = require("electron");
const path = require('path');
const fs = require('fs');
const { generalQuery, generalInsert, generalQueryCount } = require('../modules/dataBase')
const chokidar = require('chokidar');
//历史同步任务是否在进行中
let historySynchronizing = false
//历史同步任务是否在进行中
let todaySynchronizing = false
//新建资源监听
let futureWatcher = undefined
//资源监听同步任务
let futureTask = undefined

//测试：阻塞
const testAwait = () => {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve()
        }, 10000)
    })
}

//清除同步记录
const clearDataRecord = () => {
    return new Promise(resolve => {
        db.run("DELETE FROM date_record", () => {
            db.run("VACUUM", () => {
                resolve()
            });
        });
    })
}

//同步今日数据的方法
const todaySync = async () => {
    //如果目录不存在，则不执行
    const { filePath } = await getData()
    if (!filePath || filePath == '') return { error: '未设置资源目录，请先设置' }
    if (todaySynchronizing) return { error: '正在执行本任务，请稍等' }
    if (historySynchronizing) return { error: '正在执行其他同步任务，请稍等' }
    todaySynchronizing = true
    const today = new Date()
    let year = String(today.getFullYear())
    let month = today.getMonth() + 1
    let day = today.getDate()
    month = (month < 10 ? `0${month}` : String(month))
    day = (day < 10 ? `0${day}` : String(day))
    // const year = '2025'
    // const month = '02'
    // const day = '23'
    const fileDate = `${year}-${month}-${day}`
    const resourcePath = path.join(filePath, year.toString(), month, day)
    if (!fs.existsSync(resourcePath)) {
        console.error(`今日影像资源目录[${resourcePath}]不存在`)
        todaySynchronizing = false
        return { error: `今日影像资源目录[${resourcePath}]不存在` }
    }
    try {
        const studyfiles = fs.readdirSync(resourcePath);
        for (const studyName of studyfiles) {
            //研究文件夹
            const dataStrs = studyName.split('-')
            //如果研究格式不对，扔出错误
            if (dataStrs.length < 5) {
                throw new Error('studyName pattern error')
            }
            const id = encodeURIComponent(path.join(filePath, year, month, day, studyName))
            //查询此id是否存在，如果存在则跳过
            const { row: record } = await generalQuery('patient', { id }, true)
            if (record) continue
            const study = {
                id,
                bh: dataStrs[0],
                device: dataStrs[1],
                age: dataStrs[2],
                gender: dataStrs[3],
                name: dataStrs[4],
                date: fileDate
            }
            await generalInsert('patient', study)
            //检查补充记录:意味着今天是一直存在于记录当中的，同步历史数据一般不会同步今天
            const syncRecord = await generalQuery('date_record', { date: fileDate }, true).row
            if (!syncRecord) {
                await generalInsert('date_record', { date: fileDate })
            }
        }
        todaySynchronizing = false
    } catch (err) {
        todaySynchronizing = false
        return { error: '读取资源失败，请检查资源目录。\n' + err }
    }
    return { error: 0 }
}

//同步历史数据的方法
const historySync = async () => {
    //如果目录不存在，则不执行
    const { filePath } = await getData()
    if (!filePath || filePath == '') return { error: '未设置资源目录，请先设置' }
    if (historySynchronizing) return { error: '正在执行本任务，请稍等' }
    if (todaySynchronizing) return { error: '正在执行其他同步任务，请稍等' }
    historySynchronizing = true
    console.log('开始执行历史资源同步任务')
    //利用timer使用新线程处理
    setTimeout(async () => {
        //清除数据库的已同步记录
        await clearDataRecord()
        try {
            const yearfiles = fs.readdirSync(filePath);
            yearfiles.sort((a, b) => Number(b) - Number(a))
            for (const yearName of yearfiles) {
                //年份文件夹
                //如果年份格式不对，扔出错误
                if (!(/^\d{4}$/.test(yearName))) {
                    throw new Error('task: year pattern error')
                }
                const monthfiles = fs.readdirSync(path.join(filePath, yearName));
                monthfiles.sort((a, b) => Number(b) - Number(a))
                for (const monthName of monthfiles) {
                    //月份文件夹
                    //如果月份格式不对，扔出错误
                    if (!(/^\d{2}$/.test(monthName))) {
                        throw new Error('month pattern error')
                    }
                    const dayfiles = fs.readdirSync(path.join(filePath, yearName, monthName));
                    dayfiles.sort((a, b) => Number(b) - Number(a))
                    for (const dayName of dayfiles) {
                        //日期文件夹
                        //如果日期格式不对，扔出错误
                        if (!(/^\d{2}$/.test(dayName))) {
                            throw new Error('day pattern error')
                        }
                        //如果日期已被同步，跳过
                        const fileDate = `${yearName}-${monthName}-${dayName}`
                        // TODO 查询本日是否已经同步过
                        await testAwait()
                        const syncRecord = await generalQuery('date_record', { date: fileDate }, true).row
                        if (syncRecord) continue
                        const studyfiles = fs.readdirSync(path.join(filePath, yearName, monthName, dayName));
                        for (const studyName of studyfiles) {
                            //研究文件夹
                            const dataStrs = studyName.split('-')
                            //如果研究格式不对，扔出错误
                            if (dataStrs.length < 5) {
                                throw new Error('studyName pattern error')
                            }
                            const id = encodeURIComponent(path.join(filePath, yearName, monthName, dayName, studyName))
                            //查询此id是否存在，如果存在则跳过
                            const { row: record } = await generalQuery('patient', { id }, true)
                            if (record) continue
                            const study = {
                                id,
                                bh: dataStrs[0],
                                device: dataStrs[1],
                                age: dataStrs[2],
                                gender: dataStrs[3],
                                name: dataStrs[4],
                                date: fileDate
                            }
                            await generalInsert('patient', study)
                        }
                        //该日期同步完成
                        await generalInsert('date_record', { date: fileDate })
                    }
                }
            }
            historySynchronizing = false
        } catch (error) {
            historySynchronizing = false
            dialog.showErrorBox('错误', '读取资源失败，请检查资源目录。\n' + error)
        }
    })
    return { error: 0 }
}

//开启监听资源目录的方法:只监听今日文件夹新增
const futureSync = async () => {
    const { filePath } = await getData()
    if (!filePath || filePath == '') return { error: '未设置资源目录，请先设置' }
    const today = new Date()
    let year = String(today.getFullYear())
    let month = today.getMonth() + 1
    let day = today.getDate()
    month = (month < 10 ? `0${month}` : String(month))
    day = (day < 10 ? `0${day}` : String(day))
    const resourcePath = path.join(filePath, year, month, day)
    if (!fs.existsSync(resourcePath)) {
        return { error: `今日影像资源目录[${resourcePath}]不存在` }
    }
    if (futureWatcher) {
        await futureWatcher.close()
        futureWatcher = undefined
    }
    futureWatcher = chokidar.watch(resourcePath, { ignored: /(^|[\/\\])\../ }); // 忽略以点开始的文件或目录（例如 .git）
    futureWatcher.on('addDir', (path) => { // 仅当添加目录时触发
        console.log(`New directory added: ${path}`);
        //筛选掉多余情况，只保留研究文件夹这一层
        const pathStrs = path.split('\\')
        for (const [index, p] of pathStrs.entries()) {
            if (p.split('-').length == 5) {
                if (index == pathStrs.length - 1) {
                    //已确认是新增了用户研究文件夹，开始执行方法
                    //执行同步今日资源的方法，间隔10s，更新任务
                    if (futureTask) {
                        clearTimeout(futureTask)
                        futureTask = undefined
                    }
                    futureTask = setTimeout(async () => {
                        console.log('执行监听新增资源同步任务')
                        await todaySync()
                    }, 10000)
                }
            }
        }
    });
    return { error: 0 }
}


module.exports = {
    //同步数据的任务：同步本日之前的数据，每30s执行一次
    initTask() {
        //初始化任务接口
        //1.1同步历史影像资源
        ipcMain.on('TASK-EXEC-HISTORY', async (event, arg) => {
            event.returnValue = await historySync()
        })

        //1.2获取历史影像资源进度
        ipcMain.on('TASK-STATUS-HISTORY', async (event, arg) => {
            //1.获取资源总数
            const { filePath } = await getData()
            if (!filePath || filePath == '') {
                event.returnValue = { error: '未设置资源目录，请先设置' }
                return
            }
            let resourceCount = 0
            try {
                const yearfiles = fs.readdirSync(filePath);
                for (const yearName of yearfiles) {
                    //年份文件夹
                    //如果年份格式不对，扔出错误
                    if (!(/^\d{4}$/.test(yearName))) {
                        throw new Error('task: year pattern error')
                    }
                    const monthfiles = fs.readdirSync(path.join(filePath, yearName));
                    for (const monthName of monthfiles) {
                        //月份文件夹
                        //如果月份格式不对，扔出错误
                        if (!(/^\d{2}$/.test(monthName))) {
                            throw new Error('month pattern error')
                        }
                        const dayfiles = fs.readdirSync(path.join(filePath, yearName, monthName));
                        resourceCount += dayfiles.length
                    }
                }
            } catch (error) {
                event.returnValue = { error: '读取资源失败，请检查资源目录。\n' + error }
                return
            }
            //2.获取已同步资源数
            const finishedCount = await generalQueryCount('date_record')
            console.log('请求任务状态中', finishedCount, resourceCount)
            event.returnValue = { error: 0, finishedCount, resourceCount, running: historySynchronizing }
        })

        //2.今日数据同步任务
        ipcMain.on('TASK-EXEC-TODAY', async (event, arg) => {
            event.returnValue = await todaySync()
        })

        //3.监听新建资源
        ipcMain.on('TASK-EXEC-FUTURE', async (event, arg) => {
            event.returnValue = await futureSync()
        })

        //4.新增资源是否在监听中
        ipcMain.on('TASK-STATUS-FUTURE', async (event, arg) => {
            event.returnValue = { listening: futureWatcher != undefined }
        })
    },

    //执行同步今日资源的方法
    todaySync,
    //执行同步历史资源的方法
    historySync,
    //开启新资源监听的方法
    futureSync
}